package fr.sedoo.commons.metadata.utils.xml;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import net.jcip.annotations.ThreadSafe;

import org.geotoolkit.xml.MarshallerPool;
import org.geotoolkit.xml.XML;


/**
 * Creates and configures {@link Marshaller} or {@link Unmarshaller} objects for use with Geotk.
 * Users fetch (un)marshallers by calls to the {@link #acquireMarshaller()} or
 * {@link #acquireUnmarshaller()} methods.
 *
 * {@section Configuring marshallers}
 * The (un)marshallers created by this class can optionally by configured with the Geotk-specific
 * properties defined in the {@link XML} class, in addition to JAXB standard properties.
 *
 * @author Martin Desruisseaux (Geomatys)
 * @author Cédric Briançon (Geomatys)
 * @version 3.18
 *
 * @see XML
 *
 * @since 3.00
 * @module
 *
 * @todo Need a timeout for disposing marshallers that have been unused for a while.
 */

@ThreadSafe
public class RBVMarshallerPool extends MarshallerPool
{
	private final boolean internal;
	
	
	public RBVMarshallerPool(final Class<?>... classesToBeBound) throws Exception {
	    super(classesToBeBound);
	    
	    JAXBContext context = JAXBContext.newInstance(classesToBeBound);
	    internal = !context.getClass().getName().startsWith("com.sun.xml.bind");
	    
        if (internal)
        {
        	changeField(this, this.getClass().getSuperclass(), "mapper", new RBVNamespacePrefixMapper(""));
        }
        else
        {
        	changeField(this, this.getClass().getSuperclass(), "mapper", new RBVNamespacePrefixMapper_Endorsed(""));
        }
	}
	
	 public void changeField(Object object, Class clazz, String fieldName, Object value) throws IllegalAccessException, NoSuchFieldException {
		    Field field = clazz.getDeclaredField(fieldName);
		    field.setAccessible(true);
		    field.set(object, value);
		  }
	
	
}



